<template>
  <div class="bar-chart" :style="style">
    <!-- 标题和图例捆绑显示 -->
    <div class="chart-title cn-medium-16">
      {{ options.showLegend ? options.title : "" }}
    </div>
    <KCharts
      ref="barChartRef"
      :width="width"
      :height="height"
      :option="option"
      v-bind="$attrs"
      over
      @out="showTips = false"
      @over="chartsOver"
      @click="$emit('clicked', $event)"
    />
    <div v-if="showTips" class="tip" :style="labelStyle">
      {{ text }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { createBarOption } from '@/hooks/charts/bar-chart';
import type {
  Options,
  XType,
  YType,
  BaseNameDataObject
} from '@/hooks/charts/type';

defineOptions({ name: 'BarChart' });

interface YData extends BaseNameDataObject {
  barWidth?: number;
  tooltipTitles?: string[];
}
interface Props {
  width: string;
  height: string;
  grid?: any;
  legend?: any;
  tooltip?: Function;
  options?: Options;
  xType: XType;
  yType: YType;
  xData: number[] | string[];
  yData: YData[];
}
const props = withDefaults(defineProps<Props>(), {
  grid: {},
  legend: {},
  tooltip: undefined,
  options: () => {
    return {
      showLegend: true,
      legendPosition: 'topRight',
      showLabel: true,
      labelLimit: 0
    };
  }
});
defineEmits(['clicked']);
const option = ref({});
const barChartRef = ref();
const style = computed(() => {
  return {
    width: props.width,
    height: props.height
  };
});

const showTips = ref(false);
const labelStyle = ref<any>({});
const x = ref(0);
const text = ref('');
function chartsOver(val: any) {
  if (val.componentType === 'xAxis') {
    if (props.options?.labelLimit) {
      x.value = val.event.offsetX;
      labelStyle.value = { left: `${x.value}px` };
      text.value = val.value;
      if (val.value === '付费') {
        labelStyle.value = { right: '-90px' };
        text.value = '包含其他来源，如：火山、西瓜、站外分享等';
      }
      showTips.value = true;
    } else if (val.value === '付费') {
      const lastLabel = props.xData.slice().pop();
      if (lastLabel === '其他' || lastLabel === '付费') {
        labelStyle.value = { right: '-90px' };
      } else {
        x.value = val.event.offsetX;
        labelStyle.value = { left: `${x.value + 90}px` };
      }
      text.value = '包含其他来源，如：火山、西瓜、站外分享等';
      showTips.value = true;
    }
  }
}

function init() {
  let data: any = [];
  let xDataList: any = props.xData;
  if (props.yData?.length === 1) {
    xDataList = props.xData.map((item) => {
      if (item === '其他') {
        return '付费';
      }
      return item;
    });

    data = props.yData[0]?.data.slice();
    const max = Math.max.apply(null, data);
    const maxIndex = data.indexOf(max);
    data.splice(maxIndex, 1, {
      value: max,
      label: {
        color: '#4975E9'
      }
    });
  }

  option.value = createBarOption({
    grid: props.grid,
    legend: props.legend,
    tooltip: props.tooltip,
    options: props.options ?? {},
    xType: props.xType,
    yType: props.yType,
    xData: xDataList,
    yData:
      props.yData?.length === 1 ? [{ ...props.yData[0], data }] : props.yData
  });
}

watch(
  () => props.yData,
  (yData) => {
    if (!yData?.length) {
      return;
    }

    init();
  },
  {
    deep: true,
    immediate: true
  }
);
</script>

<style lang="scss" scoped>
.bar-chart {
  position: relative;
  box-sizing: border-box;

  .chart-title {
    position: absolute;
    top: -2px;
    height: 24px;
    color: #3d455f;
  }

  .tip {
    position: absolute;
    bottom: 25px;
    padding: 8px;
    font-size: var(--font-12);
    line-height: var(--line-height-12);
    color: #fff;
    text-align: center;
    background-color: rgba($color: #000, $alpha: 60%);
    border-radius: 6px;
    transform: translateX(-50%);
  }
}
</style>
